﻿using System;
using System.Threading;
using System.Web.Mvc;
using FikriKibar.Business.Abstract;
using FikriKibar.Business.Concrete;
using FikriKibar.Common.Entities;
using FikriKibar.Common.Enums;
using FikriKibar.Common.Exceptions;
using FikriKibar.Common.Helpers;
using FikriKibar.Common.Logging;
using FikriKibar.Common.Logging.Abstract;
using FikriKibar.Entities.Abstract;
using FikriKibar.Entities.Composite.UserModels;
using FikriKibar.Globalization;
using FikriKibar.UI.WebCommon.Abstract;
using FikriKibar.UI.WebCommon.Helpers;
using FikriKibar.UI.WebCommon.Infrastructure;
using FikriKibar.UI.WebCommon.Security;
using FikriKibar.UI.WebManagement.Models;


namespace FikriKibar.UI.WebManagement.Controllers
{
    public class UserController : FikriKibarController
    {
        #region Global Declarations
        private readonly ISettingService _settingService = new SettingManager();
        private readonly IUserService _userService = new UserManager();
        private readonly ISessionService _sessionService = new SessionManager();
        private readonly ILanguageService _languageService = new LanguageManager();
        private readonly IFikriKibarLogManager _logManager = new FikriKibarLogManager();
        private readonly IWebSecurityManager _webSecurityManager = new WebSecurityManager();
        #endregion
        #region Methods
        [FikriKibarSecurityFilter(1, 2)]
        public ViewResult Index()
        {
            var sessionListModel = new ListModel();
            if (Session["UserListSession"] != null)
            {
                sessionListModel = (ListModel)Session["UserListSession"];
            }
            else
            {
                sessionListModel.Paging = new Paging
                {
                    CurrentPage = 1,
                    CurrentPageSize = _settingService.GetValueByKey("DefaultPageSize").ConvertToInt()
                };
                sessionListModel.Searched = string.Empty;
                sessionListModel.SelectedRoleId = -1;
                sessionListModel.SelectedStatus = -1;
                Session["UserListSession"] = sessionListModel;
            }

            var model = _userService.GetList(sessionListModel.Searched, sessionListModel.SelectedRoleId, sessionListModel.SelectedStatus, sessionListModel.Paging.CurrentPage, sessionListModel.Paging.CurrentPageSize, null, null, null);


            return View(model);
        }

        [FikriKibarSecurityFilter(1, 2)]
        [HttpPost]
        public ActionResult Index(ListModel model)
        {
            Session["UserListSession"] = new ListModel
            {
                Paging = new Paging
                {
                    CurrentPage = model.Paging.CurrentPage,
                    CurrentPageSize = model.Paging.CurrentPageSize
                },
                Searched = model.Searched ?? string.Empty,
                SelectedRoleId = model.SelectedRoleId,
                SelectedStatus = model.SelectedStatus

            };
            return View(_userService.GetList(model.Searched ?? string.Empty, model.SelectedRoleId, model.SelectedStatus, model.Paging.CurrentPage, model.Paging.CurrentPageSize, model.IdsForSort, model.IdsForApprove, model.IdsForDelete));
        }

        [FikriKibarSecurityFilter(1, 2)]
        public ViewResult Add()
        {
            return View(_userService.Add());
        }

        [FikriKibarSecurityFilter(1, 2)]
        [HttpPost]
        public ActionResult Add(AddModel model)
        {
            try
            {
                _userService.Add(model);
                return RedirectToAction("Index", "User");
            }
            catch (ValidationException exception)
            {
                var validationResult = exception.ValidationResult;
                foreach (var t in validationResult)
                {
                    ModelState.AddModelError(t.PropertyName, t.ErrorMessage);
                }
            }

            catch (Exception exception)
            {
                model.Message = exception.Message;
            }

            finally
            {
                model.LanguageList = _languageService.GetAll();
            }
            return View(model);
        }

        [FikriKibarSecurityFilter(1, 2)]
        public ActionResult Update(string id)
        {
            try
            {
                return View(_userService.Update(id.ConvertToInt()));
            }
            catch (NotFoundException)
            {
                TempData["RedirectionModel"] = new RedirectionModel
                {
                    Message = Resources.NotFound,
                    CssClass = "alert alert-danger",
                    Timeout = 2,
                    Url = "/" + FikriKibarControllerIdentity.LanguageCode + "/User"
                };

                return RedirectToAction("Redirect", "Redirection");
            }
        }

        [FikriKibarSecurityFilter(1, 2)]
        [HttpPost]
        public ActionResult Update(UpdateModel model)
        {
            try
            {
                _userService.Update(model);

                TempData["RedirectionModel"] = new RedirectionModel
                {
                    Message = Resources.SaveSuccessMessage,
                    CssClass = "alert alert-success",
                    Timeout = 2,
                    Url = "/" + FikriKibarControllerIdentity.LanguageCode + "/User"
                };

                return RedirectToAction("Redirect", "Redirection");


            }
            catch (ValidationException exception)
            {
                var validationResult = exception.ValidationResult;
                foreach (var t in validationResult)
                {
                    ModelState.AddModelError(t.PropertyName, t.ErrorMessage);
                }
            }

            catch (Exception exception)
            {
                model.Message = exception.Message;
            }

            finally
            {
                model.LanguageList = _languageService.GetAll();
            }
            return View(model);
        }
        public ViewResult Login()
        {
            var model = _sessionService.Login();
            return View(model);
        }

        [HttpPost]
        public ActionResult Login(LoginModel model)
        {
            try
            {
                CaptchaHelper.SetCaptcha(model);
                if (CaptchaHelper.HasError)
                {
                    ModelState.AddModelError("CaptchaValue", CaptchaHelper.ErrorMessage);
                    return View(model);
                }

                _sessionService.Login(model);
                _webSecurityManager.Set(FikriKibarControllerIdentity, DateTime.Now.AddMinutes(_settingService.GetValueByKey("SessionTimeOut").ConvertToInt()), Constants.PrivateCookieName, FikriKibarControllerIdentity.RememberMe);

                var fikriKibarPrincipal = (FikriKibarPrincipal)Thread.CurrentPrincipal;
                System.Web.HttpContext.Current.User = fikriKibarPrincipal;


                TempData["RedirectionModel"] = new RedirectionModel
                {
                    Message = Resources.LoginSuccessMessage,
                    CssClass = "alert alert-success",
                    Timeout = 2,
                    Url = "/" + FikriKibarControllerIdentity.LanguageCode + "/User/MyAccount"
                };

                return RedirectToAction("Redirect", "Redirection");
            }

            catch (ValidationException exception)
            {
                var validationResult = exception.ValidationResult;
                foreach (var t in validationResult)
                {
                    ModelState.AddModelError(t.PropertyName, t.ErrorMessage);
                }
            }

            catch (Exception exception)
            {
                _logManager.Log(GetType(), exception.InnerException?.ToString() ?? exception.Message, LogOptions.Error);             
                model.Message = exception.Message;
            }

            finally
            {
                model.LanguageList = _languageService.GetAll();
            }

            return View(model);
        }
        public ViewResult ForgotPassword()
        {
            var model = _userService.ForgotPassword();
            return View(model);
        }

        [HttpPost]
        public ActionResult ForgotPassword(UpdateModel model)
        {
            try
            {
                CaptchaHelper.SetCaptcha(model);
                if (CaptchaHelper.HasError)
                {
                    ModelState.AddModelError("CaptchaValue", CaptchaHelper.ErrorMessage);
                    return View(model);
                }
                _userService.ForgotPassword(model);

                TempData["RedirectionModel"] = new RedirectionModel
                {
                    Message = Resources.ForgotPasswordMessage,
                    CssClass = "alert alert-success",
                    Timeout = 2,
                    Url = "/"
                };

                return RedirectToAction("Redirect", "Redirection");


            }

            catch (ValidationException exception)
            {
                var validationResult = exception.ValidationResult;
                foreach (var t in validationResult)
                {
                    ModelState.AddModelError(t.PropertyName, t.ErrorMessage);
                }
            }

            catch (Exception exception)
            {
                model.Message = exception.Message;
            }

            finally
            {
                model.LanguageList = _languageService.GetAll();
            }

            return View(model);
        }
        public ViewResult SignUp()
        {
            var model = _userService.SignUp();
            return View(model);
        }

        [HttpPost]
        public ActionResult SignUp(AddModel model)
        {
            model.LanguageList = _languageService.GetAll();
            try
            {
                CaptchaHelper.SetCaptcha(model);
                if (CaptchaHelper.HasError)
                {
                    ModelState.AddModelError("CaptchaValue", CaptchaHelper.ErrorMessage);
                    return View(model);
                }
                _userService.SignUp(model);

                TempData["RedirectionModel"] = new RedirectionModel
                {
                    Message = Resources.ForgotPasswordMessage,
                    CssClass = "alert alert-success",
                    Timeout = 2,
                    Url = "/"
                };

                return RedirectToAction("Redirect", "Redirection");


            }
            catch (ValidationException exception)
            {
                var validationResult = exception.ValidationResult;
                foreach (var t in validationResult)
                {
                    ModelState.AddModelError("User." + t.PropertyName, t.ErrorMessage);
                }
            }

            catch (Exception exception)
            {
                model.Message = exception.Message;
            }
            return View(model);
        }

        [FikriKibarSecurityFilter]
        public ViewResult MyAccount()
        {
            return View(_userService.MyAccount());
        }

        [FikriKibarSecurityFilter]
        public ViewResult UpdateMyInformation()
        {
            var model = _userService.UpdateMyInformation();
            return View(model);
        }

        [FikriKibarSecurityFilter]
        [HttpPost]
        public ActionResult UpdateMyInformation(UpdateModel model)
        {
            model.LanguageList = _languageService.GetAll();
            try
            {
                _userService.UpdateMyInformation(model);
                TempData["RedirectionModel"] = new RedirectionModel
                {
                    Message = Resources.UpdateMyInformationSuccessMessage,
                    CssClass = "alert alert-success",
                    Timeout = 2,
                    Url = "/" + FikriKibarControllerIdentity.LanguageCode + "/User/MyAccount"
                };

                return RedirectToAction("Redirect", "Redirection");



            }
            catch (ValidationException exception)
            {
                foreach (var t in exception.ValidationResult)
                {
                    ModelState.AddModelError("User." + t.PropertyName, t.ErrorMessage);
                }
            }
            catch (Exception exception)
            {
                model.Message = exception.Message;
            }

            return View(model);
        }

        [FikriKibarSecurityFilter]
        public ViewResult UpdateMyPassword()
        {
            var model = _userService.UpdateMyPassword();
            return View(model);
        }

        [FikriKibarSecurityFilter]
        [HttpPost]
        public ActionResult UpdateMyPassword(UpdateModel model)
        {
            try
            {
                _userService.UpdateMyPassword(model);


                TempData["RedirectionModel"] = new RedirectionModel
                {
                    Message = Resources.UpdateMyPasswordSuccessMessage,
                    CssClass = "alert alert-success",
                    Timeout = 2,
                    Url = "/" + FikriKibarControllerIdentity.LanguageCode + "/User/MyAccount"
                };

                return RedirectToAction("Redirect", "Redirection");



            }
            catch (ValidationException exception)
            {
                foreach (var t in exception.ValidationResult)
                {
                    ModelState.AddModelError("User." + t.PropertyName, t.ErrorMessage);
                }
            }
            catch (Exception exception)
            {
                model.Message = exception.Message;
            }
            return View(model);
        }

        public ActionResult Logout()
        {
            _sessionService.Logout(LogoutOptions.ValidLogut);
            _webSecurityManager.Remove(Constants.PrivateCookieName);
            var fikriKibarPrinciple = (FikriKibarPrincipal)Thread.CurrentPrincipal;
            HttpContext.User = fikriKibarPrinciple;


            TempData["RedirectionModel"] = new RedirectionModel
            {
                Message = Resources.Logout,
                CssClass = "alert alert-success",
                Timeout = 2,
                Url = "/"
            };

            return RedirectToAction("Redirect", "Redirection");


        }

        [FikriKibarSecurityFilter]
        public ViewResult Header()
        {
            var account = _userService.MyAccount();
            var model = new HeaderModel
            {
                LanguageList = _languageService.GetAll(),
                LastLoginTime = account.LastLoginTime,
                RemainingSessionTime = account.RemainingSessionTime,
                ApplicationName = _settingService.GetValueByKey("ApplicationName")
            };
            return View(model);
        }

        public ViewResult UserSidebar()
        {
            return View(_userService.MyAccount());
        }


        public ActionResult TimeOutLogout()
        {
            _sessionService.Logout(LogoutOptions.TimeOut);



            TempData["RedirectionModel"] = new RedirectionModel
            {
                Message = Resources.SessionTimeOutMessage,
                CssClass = "alert alert-danger",
                Timeout = 2,
                Url = "/" + FikriKibarControllerIdentity.LanguageCode + "/User/Login"
            };
            return RedirectToAction("Redirect", "Redirection");

        }

        [FikriKibarSecurityFilter(1, 2)]
        public ActionResult Delete(int id)
        {
            _userService.Delete(id);

            TempData["RedirectionModel"] = new RedirectionModel
            {
                Message = Resources.DeleteSuccessMessage,
                CssClass = "alert alert-success",
                Timeout = 2,
                Url = "/" + FikriKibarControllerIdentity.LanguageCode + "/User"
            };

            return RedirectToAction("Redirect", "Redirection");


        }
        #endregion
    }
}